<template>
  <el-dialog
    v-model="dialogVisible"
    :title="title"
    :width="width"
    :fullscreen="fullscreen"
    :top="top"
    :modal="modal"
    :modal-append-to-body="modalAppendToBody"
    :append-to-body="appendToBody"
    :destroy-on-close="destroyOnClose"
    :before-close="handleBeforeClose"
    :close-on-click-modal="closeOnClickModal"
    :close-on-press-escape="closeOnPressEscape"
    :show-close="showClose"
    :size="size"
    class="dialog-form"
    @open="handleOpen"
    @close="handleClose"
  >
    <!-- 表单内容 -->
    <el-form
      ref="formRef"
      :model="formData"
      :rules="rules"
      :label-width="labelWidth"
      :inline="inline"
      class="dialog-form-content"
    >
      <!-- 动态渲染表单项 -->
      <template v-for="(item, index) in formItems" :key="index">
        <!-- 表单分组 -->
        <div v-if="item.type === 'group'" class="form-group">
          <div class="form-group-title">{{ item.title }}</div>
          <div class="form-group-content">
            <template v-for="(subItem, subIndex) in item.items" :key="subIndex">
              <el-form-item
                :label="subItem.label"
                :prop="subItem.prop"
                :rules="getItemRules(subItem.prop)"
                :required="subItem.required"
                :validate-event="subItem.validateEvent !== false"
                :span="subItem.span || 24"
              >
                <!-- 渲染子表单项 -->
                <render-form-item :item="subItem" :form-data="formData" />
              </el-form-item>
            </template>
          </div>
        </div>
        <!-- 普通表单项 -->
        <el-form-item
          v-else
          :label="item.label"
          :prop="item.prop"
          :rules="getItemRules(item.prop)"
          :required="item.required"
          :validate-event="item.validateEvent !== false"
          :span="item.span || 24"
        >
          <!-- 渲染表单项 -->
          <render-form-item :item="item" :form-data="formData" />
        </el-form-item>
      </template>
    </el-form>

    <!-- 底部操作按钮 -->
    <template #footer>
      <div class="dialog-form-actions">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" @click="handleSubmit" :loading="loading">
          {{ confirmText }}
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, reactive, computed, watch } from 'vue'
import RenderFormItem from './RenderFormItem.vue'
import { message } from '@/utils/message'

// 定义组件的props
const props = defineProps({
  // 对话框可见性
  visible: {
    type: Boolean,
    default: false
  },
  // 对话框标题
  title: {
    type: String,
    default: '新增'
  },
  // 对话框宽度
  width: {
    type: String,
    default: '50%'
  },
  // 是否全屏
  fullscreen: {
    type: Boolean,
    default: false
  },
  // 对话框距离顶部的距离
  top: {
    type: String,
    default: '15vh'
  },
  // 是否显示遮罩层
  modal: {
    type: Boolean,
    default: true
  },
  // 遮罩层是否插入至 body 元素上
  modalAppendToBody: {
    type: Boolean,
    default: true
  },
  // 对话框自身是否插入至 body 元素上
  appendToBody: {
    type: Boolean,
    default: false
  },
  // 关闭时销毁 Dialog 中的元素
  destroyOnClose: {
    type: Boolean,
    default: false
  },
  // 点击遮罩层是否关闭对话框
  closeOnClickModal: {
    type: Boolean,
    default: true
  },
  // 按 ESC 键是否关闭对话框
  closeOnPressEscape: {
    type: Boolean,
    default: true
  },
  // 是否显示关闭按钮
  showClose: {
    type: Boolean,
    default: true
  },
  // 对话框大小
  size: {
    type: String,
    default: 'default'
  },
  // 表单配置项
  formItems: {
    type: Array,
    required: true,
    default: () => []
  },
  // 表单规则
  rules: {
    type: Object,
    default: () => ({})
  },
  // 表单数据
  formData: {
    type: Object,
    default: () => ({})
  },
  // 标签宽度
  labelWidth: {
    type: String,
    default: '100px'
  },
  // 是否为内联表单
  inline: {
    type: Boolean,
    default: false
  },
  // 确认按钮文本
  confirmText: {
    type: String,
    default: '确定'
  },
  // 加载状态
  loading: {
    type: Boolean,
    default: false
  }
})

// 定义事件
const emit = defineEmits([
  'update:visible',
  'open',
  'close',
  'submit',
  'cancel',
  'before-close'
])

// 对话框可见性
const dialogVisible = ref(false)

// 表单引用
const formRef = ref(null)

// 表单数据（深拷贝props中的formData）
const localFormData = reactive({ ...props.formData })

// 监听visible变化
watch(() => props.visible, (newValue) => {
  dialogVisible.value = newValue
})

// 监听dialogVisible变化，通知父组件
watch(dialogVisible, (newValue) => {
  emit('update:visible', newValue)
})

// 监听formData变化，更新本地数据
watch(() => props.formData, (newValue) => {
  Object.assign(localFormData, newValue)
}, { deep: true })

// 获取表单项规则
function getItemRules(prop) {
  return props.rules[prop] || []
}

// 处理对话框打开
function handleOpen() {
  emit('open')
}

// 处理对话框关闭
function handleClose() {
  emit('close')
  // 如果是销毁模式，重置表单
  if (props.destroyOnClose) {
    resetForm()
  }
}

// 处理对话框关闭前
function handleBeforeClose(done) {
  emit('before-close', done)
}

// 处理取消
function handleCancel() {
  emit('cancel')
  dialogVisible.value = false
}

// 处理提交
async function handleSubmit() {
  if (!formRef.value) return
  
  try {
    // 表单验证
    await formRef.value.validate()
    // 提交表单数据
    emit('submit', { ...localFormData })
  } catch (error) {
    message.error('表单验证失败，请检查输入内容')
  }
}

// 重置表单
function resetForm() {
  if (formRef.value) {
    formRef.value.resetFields()
  }
}

// 清除表单验证
function clearValidate(prop) {
  if (formRef.value) {
    if (prop) {
      formRef.value.clearValidate(prop)
    } else {
      formRef.value.clearValidate()
    }
  }
}

// 暴露方法给父组件
defineExpose({
  formRef,
  resetForm,
  clearValidate,
  validate: async () => {
    if (formRef.value) {
      return formRef.value.validate()
    }
    return Promise.resolve()
  },
  validateField: (prop, callback) => {
    if (formRef.value) {
      formRef.value.validateField(prop, callback)
    }
  }
})
</script>

<style scoped>
.dialog-form {
  border-radius: 4px;
}

.dialog-form-content {
  max-height: 400px;
  overflow-y: auto;
  padding-right: 8px;
}

.dialog-form-actions {
  text-align: right;
}

.form-group {
  margin-bottom: 20px;
  padding: 16px;
  background-color: #f5f7fa;
  border-radius: 4px;
}

.form-group-title {
  font-weight: 500;
  margin-bottom: 12px;
  color: #303133;
}

.form-group-content {
  display: flex;
  flex-wrap: wrap;
  margin: -8px;
}

.form-group-content :deep(.el-form-item) {
  margin: 8px;
  width: calc(50% - 16px);
}

.form-group-content :deep(.el-form-item.is-required > label:first-child::before) {
  content: '*';
  color: #f56c6c;
  margin-right: 4px;
}

:deep(.el-form-item) {
  margin-bottom: 16px;
}

:deep(.el-input__wrapper),
:deep(.el-select__wrapper),
:deep(.el-date-editor) {
  box-shadow: none !important;
}

:deep(.el-input__wrapper.is-focused),
:deep(.el-select__wrapper.is-focused),
:deep(.el-date-editor.is-active) {
  border-color: #1890ff !important;
}

/* 滚动条样式 */
.dialog-form-content::-webkit-scrollbar {
  width: 6px;
}

.dialog-form-content::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

.dialog-form-content::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.dialog-form-content::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

/* 响应式布局 */
@media screen and (max-width: 768px) {
  .dialog-form {
    width: 90% !important;
    top: 10px !important;
  }
  
  .form-group-content :deep(.el-form-item) {
    width: 100%;
  }
}
</style>